/*
    yandexnarodPlugin

    Copyright (c) 2008 by Alexander Kazarin <boiler@co.ru>

 ***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************
*/

#include "yandexnarod.h"
#include "requestauthdialog.h"

bool yandexnarodPlugin::init(PluginSystemInterface *plugin_system)
{
	qRegisterMetaType<TreeModelItem>("TreeModelItem");

	PluginInterface::init(plugin_system);
	m_plugin_icon = new QIcon(":/icons/yandexnarodplugin.png");
	m_plugin_system = plugin_system;

	QAction* menuaction = new QAction(QIcon(":/icons/yandexnarodplugin.png"), tr("Send file via Yandex.Narod"), this);
	connect(menuaction, SIGNAL(triggered()), this,  SLOT(actionStart()));
	emit m_plugin_system->registerContactMenuAction(menuaction, this);

	msgtemplate = "File sent: %N (%S bytes)\n%U";
	
	return true;
}

void yandexnarodPlugin::release()
{
	
}

void yandexnarodPlugin::processEvent(PluginEvent &event)
{
	if ( event.system_event_type == ContactContextAction ) {
		eventitem = *(TreeModelItem*)(event.args.at(0));
	}
}

QWidget *yandexnarodPlugin::settingsWidget()
{
	QSettings settings(QSettings::IniFormat, QSettings::UserScope, "qutim/qutim."+m_profile_name, "plugin_yandexnarod");
	narodLogin = settings.value("auth/login").toString();
	narodPasswd = settings.value("auth/passwd").toString();
	if (settings.value("main/msgtemplate").isValid()) {
		msgtemplate = settings.value("main/msgtemplate").toString();
	}
	settingswidget = new yandexnarodSettings(m_profile_name);
	connect(settingswidget, SIGNAL(testclick()), this,  SLOT(on_btnTest_clicked()));
	return settingswidget;
}

void yandexnarodPlugin::setProfileName(const QString &profile_name)
{
	m_profile_name = profile_name;
}

QString yandexnarodPlugin::name()
{
	return "Yandex.Narod";
}

QString yandexnarodPlugin::description()
{
	return "Send files via Yandex.Narod file exchange service";
}

QIcon *yandexnarodPlugin::icon()
{
	return m_plugin_icon;
}

QString yandexnarodPlugin::type()
{
	return "other";
}


void yandexnarodPlugin::removeSettingsWidget()
{
	delete settingsWidget();
}

void yandexnarodPlugin::saveSettings()
{
	settingswidget->saveSettings();
}

void yandexnarodPlugin::on_btnTest_clicked()
{
	narodLogin = settingswidget->getLogin();
	narodPasswd = settingswidget->getPasswd();
	authtest=true;
	cooks.clear();
	settingswidget->btnTest_enabled(false);
	nstep=0; netreqNext();
}

void yandexnarodPlugin::actionStart()
{
	QSettings settings(QSettings::IniFormat, QSettings::UserScope, "qutim/qutim."+m_profile_name, "plugin_yandexnarod");
	narodLogin = settings.value("auth/login").toString();
	narodPasswd = settings.value("auth/passwd").toString();
	if (settings.value("main/msgtemplate").isValid()) msgtemplate = settings.value("main/msgtemplate").toString();
	uploadwidget = new uploadDialog();
	connect(uploadwidget, SIGNAL(canceled()), this, SLOT(removeUploadWidget()));
	uploadwidget->show();

	authtest=false;
	cooks.clear();
	nstep=0;
	netreqNext();
}

void yandexnarodPlugin::actionError(QString error) {
	uploadwidget->setStatus(error);
}

void yandexnarodPlugin::netreqNext() {
	QSettings settings(QSettings::IniFormat, QSettings::UserScope, "qutim/qutim."+m_profile_name, "plugin_yandexnarod");
	netman = new QNetworkAccessManager();
	QNetworkRequest netreq;
	QNetworkReply* netrp;

	connect ( netman, SIGNAL ( finished( QNetworkReply* ) ), this, SLOT ( netrpFinished( QNetworkReply* ) ) );
	for (int i=0; i<cooks.size(); ++i) netreq.setRawHeader("Cookie", cooks[i].toLatin1());

	QString error;
	
	if (nstep==0) {
		if (!authtest && (narodLogin.isEmpty() || narodPasswd.isEmpty())) {
			uploadwidget->setStatus("Login or password is empty in settings");
			requestAuthDialog authdialog;
			authdialog.setLogin(narodLogin);
			if (authdialog.exec()) {
				narodLogin = authdialog.getLogin();
				narodPasswd = authdialog.getPasswd();
				netreqNext();
			}
		}
		else {
			netreq.setUrl(QUrl("http://passport.yandex.ru/passport?mode=auth"));
			if (authtest) settingswidget->setStatus("Authorization...");
			else uploadwidget->setStatus("Authorization...");
			netrp = netman->post(netreq, "login=" + narodLogin.toLatin1() + "&passwd=" + narodPasswd.toLatin1());
		}
	}
	else if (nstep==1) {
		netreq.setUrl(QUrl("http://narod.yandex.ru/disk/getstorage/"));
		for (int i=0; i<cooks.size(); ++i) netreq.setRawHeader("Cookie", cooks[i].toLatin1());
		uploadwidget->setStatus("Getting storage...");
		netrp = netman->get(netreq);
	}
	else if (nstep==2) {
		QRegExp rx("\"url\":\"(\\S+)\".+\"hash\":\"(\\S+)\".+\"purl\":\"(\\S+)\"");
		rx.indexIn(page);
		netreq.setUrl(QUrl(rx.capturedTexts()[1] + "?tid=" + rx.capturedTexts()[2]));
		purl = rx.capturedTexts()[3] + "?tid=" + rx.capturedTexts()[2];
		uploadwidget->setStatus("Opening file...");

		QString boundary = "AaB03x";

		QString filepath = QFileDialog::getOpenFileName(uploadwidget, tr("Choose file"), settings.value("main/lastdir").toString());
		QFile file(filepath);
		fi.setFile(file);
		if (filepath.isEmpty()) {
			uploadwidget->setStatus("Canceled");
			removeUploadWidget();
		}
		else if (fi.size()==0) {
			uploadwidget->setStatus("File size is null");
		}
		else if (file.open(QIODevice::ReadOnly)) {
			settings.setValue("main/lastdir", fi.dir().path());
			QString fName = fi.fileName();

			uploadwidget->setStatus("Starting upload...");

			QByteArray mpData;
			mpData.append("--" + boundary + "\r\n");
			mpData.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + fName.toUtf8() + "\"\r\n");
			mpData.append("Content-Transfer-Encoding: binary\r\n");
			mpData.append("\r\n");
			mpData.append(file.readAll());
			mpData.append("\r\n--" + boundary + "--\r\n");

			file.close();

			netreq.setRawHeader("Content-Type", "multipart/form-data, boundary=" + boundary.toLatin1());
			netreq.setRawHeader("Cache-Control", "no-cache");
			netreq.setRawHeader("Accept", "*/*");
			netreq.setRawHeader("Content-Length", QString::number(mpData.length()).toLatin1());
			for (int i=0; i<cooks.size(); ++i) netreq.setRawHeader("Cookie", cooks[i].toLatin1());

//			time.start();
			uploadwidget->setFilename(fName);

			netrp = netman->post(netreq, mpData);
			connect(netrp, SIGNAL(uploadProgress(qint64, qint64)), uploadwidget, SLOT(progress(qint64, qint64)));
		}
		else {
			uploadwidget->setStatus("Can't read file");
		}
		
	}
	if (nstep==3) {
		netreq.setUrl(QUrl(purl));
		uploadwidget->setStatus("Verifying...");
		netrp = netman->get(netreq);
	}
	if (nstep==4) {
		netreq.setUrl(QUrl("http://narod.yandex.ru/disk/last"));
		netrp = netman->get(netreq);
	}

}

void yandexnarodPlugin::netrpFinished( QNetworkReply* reply )
{
	if (nstep==0) {
		bool auth_ok=false;
		QString cookstr = reply->rawHeader("Set-Cookie");
		QStringList cooklist = cookstr.split(", ");
		for (int i=0; i<cooklist.size(); ++i) {
			QStringList cookargs = cooklist[i].split("; ");
			cooks.append(cookargs[0]);
			QStringList cookval = cookargs[0].split("=");
			if (cookval[0]=="yandex_login" && !cookval[1].isEmpty()) {
				auth_ok=true;
			}
		}
		if (authtest) settingswidget->btnTest_enabled(false);
		if (auth_ok) {
			if (authtest) {
				settingswidget->setStatus("Authorization OK");
			} 
			else { nstep++; netreqNext(); }
		}
		else {
			if (authtest) {
				settingswidget->setStatus("Authorization failed");
			}
			else actionError("Authorization failed");
		}
	}
	else if (nstep==1) {
		page = reply->readAll();
		nstep++; netreqNext();
	}
	else if (nstep==2) {
		nstep++; netreqNext();
	}
	else if (nstep==3) {
		page = reply->readAll();
		QRegExp rx("\"status\":\\s+\"done\"");
		if (rx.indexIn(page)>0) {
			nstep++; netreqNext();
		}
		else {
			uploadwidget->setStatus("Upload failed");
		}
	}
	else if (nstep==4) {
		page = reply->readAll();
		QRegExp rx("<span\\sclass='b-fname'><a\\shref=\"(\\S+)\"");
		rx.indexIn(page);
		QString sendurl = rx.capturedTexts()[1];
		QString sendmsg = msgtemplate;
		sendmsg.replace("%N", fi.fileName());
		sendmsg.replace("%U", sendurl);
		sendmsg.replace("%S", QString::number(fi.size()));
		emit m_plugin_system->sendCustomMessage(eventitem, sendmsg);
		uploadwidget->setStatus("File sent");
		removeUploadWidget();
	}
}

void yandexnarodPlugin::removeUploadWidget()
{
	netman->disconnect();
	delete netman;
	uploadwidget->close();
//	delete uploadwidget;
}


Q_EXPORT_PLUGIN2(yandexnarodPlugin,yandexnarodPlugin);
